package com.andong.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.andong.domain.entity.Student;
import com.andong.domain.entity.VehicleBooking;
import com.andong.domain.pojo.PageResult;
import com.andong.domain.pojo.Result;
import com.andong.domain.vo.VehicleVO;
import com.andong.service.VehicleBookingService;
import com.andong.utils.AliOSSUtils;
import com.andong.utils.BaseContext;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.andong.domain.entity.Vehicle;
import com.andong.service.VehicleService;
import com.andong.mapper.VehicleMapper;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

import static com.andong.utils.SystemConstant.*;

/**
* @author 王海云
* @description 针对表【vehicle(车辆信息表)】的数据库操作Service实现
* @createDate 2024-01-03 18:19:57
*/
@Service
@Slf4j
public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle>
    implements VehicleService{
    @Resource
    private VehicleBookingService driveBookingService;
    @Resource
    private AliOSSUtils aliOSSUtils;
    @Override
    @Transactional
    public Result delete(Long id) {
        // 1.首先查看是否存在预约车辆在id中
        Long count = driveBookingService.lambdaQuery()
                .gt(VehicleBooking::getBookingTime, LocalDateTime.now())
                .eq(VehicleBooking::getVehicleId, id)
                .count();
        if (count > 0) {
            return Result.error(VEHICLE_BOOKING_DELETE_ERROR);
        }
        // 删除车辆照片
        aliOSSUtils.delete(getById(id).getImage());
        removeById(id);
        return Result.success();
    }

    @Override
    public Result modify(Vehicle vehicle) {
        // 预约中的车辆不允许修改
        Long count = driveBookingService.lambdaQuery()
                .gt(VehicleBooking::getBookingTime, LocalDateTime.now())
                .eq(VehicleBooking::getVehicleId, vehicle.getId())
                .count();
        if (count > 0) {
            return Result.error(VEHICLE_BOOKING_UPDATE_ERROR);
        }
        updateById(vehicle);
        return Result.success();
    }

    @Override
    public PageResult queryList(Integer page, Integer pageSize, Integer status, Integer type, String plateNumber, LocalDate begin, LocalDate end) {
        // 判断当前是否是学员查询
        Student student;
        String identity = (String) BaseContext.getCurrentIdAndIdentity().get(CURRENT_IDENTITY);
        System.out.println("当前身份为：" + identity);
        Integer studentLicenseType = null;
        if (STUDENT.equals(identity)) {
            Long id = (Long) BaseContext.getCurrentIdAndIdentity().get(CURRENT_ID);
            // 查询学员驾照类型
            student = Db.lambdaQuery(Student.class)
                    .eq(Student::getId, id)
                    .one();
            studentLicenseType = student.getLicenseType();
        }
        // 构造Student分页器
        Page<Vehicle> vehiclePage = new Page<>(page, pageSize);
        // 构造Student条件查询器, 得到Student分页查询基本信息结果
        vehiclePage = lambdaQuery()
                .eq(status != null, Vehicle::getStatus, status)
                .eq(type != null, Vehicle::getType, type)
                .eq(STUDENT.equals(identity), Vehicle::getType, studentLicenseType)
                .ge(begin != null, Vehicle::getCreateTime, begin)
                .le(end != null, Vehicle::getCreateTime, end)
                .like(plateNumber != null, Vehicle::getPlateNumber, plateNumber)
                .orderByDesc(Vehicle::getCreateTime)
                .page(vehiclePage);
        // 使用stream流的方式对记录中的每一条数据进行处理
        List<Vehicle> records = vehiclePage.getRecords();
        List<VehicleVO> voList = records.stream().map(recode -> {
            VehicleVO vehicleVO = new VehicleVO();
            BeanUtil.copyProperties(recode, vehicleVO);
            // 查询预约人数
            Long count = Db.lambdaQuery(VehicleBooking.class)
                    .eq(VehicleBooking::getVehicleId, recode.getId())
                    .gt(VehicleBooking::getBookingTime, LocalDateTime.now())
                    .count();
            vehicleVO.setNumber(count);
            return vehicleVO;
        }).toList();
        return new PageResult(vehiclePage.getTotal(), voList);
    }

    @Override
    public Result add(Vehicle vehicle) {
        // 查询车牌号是否存在
        Long count = lambdaQuery()
                .eq(Vehicle::getPlateNumber, vehicle.getPlateNumber())
                .count();
        if (count > 0) {
            return Result.error(VEHICLE_EXISTS);
        }
        save(vehicle);
        return Result.success();
    }

    @Override
    public Result updateStatus(Long id, Integer status) {
        lambdaUpdate()
                .eq(Vehicle::getId, id)
                .set(Vehicle::getStatus, status)
                .update(getById(id));
        return Result.success();
    }
}




